import { Logger } from './logger';
import { IDebuggerConfig } from './debugConfig';

export interface IProtocolMessage {
    seq: number;
    type: string;
    command?: string;
    event?: string;
    body?: any;
    success?: boolean;
    message?: string;
}

export class ProtocolHandler {
    private logger: Logger;
    private buffer = '';
    private sequenceNumber = 0;

    constructor() {
        this.logger = Logger.getInstance();
    }

    public handleData(data: Buffer): void {
        this.buffer += data.toString();

        let newlineIndex: number;
        while ((newlineIndex = this.buffer.indexOf('\n')) !== -1) {
            const line = this.buffer.substring(0, newlineIndex).trim();
            this.buffer = this.buffer.substring(newlineIndex + 1);

            if (line) {
                try {
                    const message = JSON.parse(line);
                    this.processMessage(message);
                } catch (error) {
                    this.logger.error(`解析消息失败: ${line} - ${(error as Error).message}`);
                }
            }
        }
    }

    private processMessage(message: IProtocolMessage): void {
        try {
            this.logger.debug(`处理消息: ${JSON.stringify(message)}`);
            // 处理消息的具体逻辑
        } catch (error) {
            this.logger.error(`处理消息失败: ${(error as Error).message}`);
        }
    }

    public parseMessage(data: string): IProtocolMessage[] {
        this.buffer += data;
        const messages: IProtocolMessage[] = [];
        let endIndex: number;

        while ((endIndex = this.buffer.indexOf('\n')) !== -1) {
            const line = this.buffer.substring(0, endIndex).trim();
            this.buffer = this.buffer.substring(endIndex + 1);

            if (line.length > 0) {
                try {
                    const message = this.parseLine(line);
                    if (message) {
                        messages.push(message);
                    }
                } catch (error) {
                    this.logger.error(`Failed to parse message: ${line}`, error as Error);
                }
            }
        }

        return messages;
    }

    private parseLine(line: string): IProtocolMessage | null {
        // 解析命令响应
        if (line.startsWith('^')) {
            const match = line.match(/^(\d+)\^(done|running|error|exit)(?:,(.*))?$/);
            if (match) {
                const [, seq, type, body] = match;
                return {
                    type: 'response',
                    seq: parseInt(seq),
                    success: type !== 'error',
                    message: type,
                    body: this.parseBody(body)
                };
            }
        }
        // 解析异步事件
        else if (line.startsWith('*')) {
            const match = line.match(/^\*([^,]+)(?:,(.*))?$/);
            if (match) {
                const [, event, body] = match;
                return {
                    type: 'event',
                    seq: ++this.sequenceNumber,
                    event,
                    body: this.parseBody(body)
                };
            }
        }
        // 解析控制台输出
        else if (line.startsWith('~')) {
            return {
                type: 'event',
                seq: ++this.sequenceNumber,
                event: 'output',
                body: {
                    category: 'console',
                    output: line.substring(1).trim()
                }
            };
        }
        // 解析目标输出
        else if (line.startsWith('@')) {
            return {
                type: 'event',
                seq: ++this.sequenceNumber,
                event: 'output',
                body: {
                    category: 'target',
                    output: line.substring(1).trim()
                }
            };
        }
        // 解析日志输出
        else if (line.startsWith('&')) {
            return {
                type: 'event',
                seq: ++this.sequenceNumber,
                event: 'output',
                body: {
                    category: 'log',
                    output: line.substring(1).trim()
                }
            };
        }

        return null;
    }

    private parseBody(body: string | undefined): any {
        if (!body) {
            return undefined;
        }

        const result: any = {};
        const pairs = body.split(',');

        for (const pair of pairs) {
            const [key, ...values] = pair.split('=');
            const value = values.join('=');

            if (key && value) {
                // 处理字符串值
                if (value.startsWith('"') && value.endsWith('"')) {
                    result[key] = value.slice(1, -1);
                }
                // 处理数组
                else if (value.startsWith('[') && value.endsWith(']')) {
                    result[key] = this.parseArray(value);
                }
                // 处理对象
                else if (value.startsWith('{') && value.endsWith('}')) {
                    result[key] = this.parseObject(value);
                }
                // 处理数字
                else if (/^-?\d+$/.test(value)) {
                    result[key] = parseInt(value);
                }
                // 处理布尔值
                else if (value === 'true' || value === 'false') {
                    result[key] = value === 'true';
                }
                // 其他情况作为字符串处理
                else {
                    result[key] = value;
                }
            }
        }

        return result;
    }

    private parseArray(arrayStr: string): any[] {
        // 移除方括号
        const content = arrayStr.slice(1, -1);
        if (!content) {
            return [];
        }

        // 分割并解析每个元素
        return content.split(',').map(item => {
            item = item.trim();
            if (item.startsWith('"') && item.endsWith('"')) {
                return item.slice(1, -1);
            }
            if (/^-?\d+$/.test(item)) {
                return parseInt(item);
            }
            if (item === 'true' || item === 'false') {
                return item === 'true';
            }
            return item;
        });
    }

    private parseObject(objectStr: string): any {
        // 移除花括号
        const content = objectStr.slice(1, -1);
        if (!content) {
            return {};
        }

        return this.parseBody(content);
    }

    public createRequest(command: string, args?: any): string {
        const seq = ++this.sequenceNumber;
        let request = `${seq}-${command}`;

        if (args) {
            const argStr = Object.entries(args)
                .map(([key, value]) => {
                    if (typeof value === 'string') {
                        return `${key}="${value}"`;
                    }
                    return `${key}=${value}`;
                })
                .join(' ');

            if (argStr) {
                request += ` ${argStr}`;
            }
        }

        this.logger.debug(`Creating request: ${request}`);
        return request + '\n';
    }

    public createResponse(request: IProtocolMessage, success: boolean, message?: string, body?: any): IProtocolMessage {
        return {
            seq: this.sequenceNumber++,
            type: 'response',
            command: request.command,
            success,
            message,
            body
        };
    }
} 